﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace MrPoetic.MatLab.Hash
{
    /// <summary>
    /// 高级加密标准（英语：Advanced Encryption Standard，缩写：AES），在密码学中又称Rijndael加密法，
    /// 是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES，已经被多方分析且广为全世界所使
    /// 用。它要求区块大小必须为128位，而密钥长度则可以为128、196、256位。基于此我们来实现.NET 
    /// Framework版本和.NET Core版本
    /// </summary>
    public static class RSAIMPL
    {
        /// <summary>
        ///  AES 加密
        /// </summary>
        /// <param name="content">明文（待加密）</param>
        /// <param name="key">密文</param>
        /// <returns>string</returns>
        /// <summary>    
        public static string AESEncrypto(string Data, string Key)
        {
            // 秘钥必须是32位的 向量理论是16位的
            var _32Key = Key.ToHashString(HashType.MD5);
            var Hash = Encoding.UTF8.GetBytes(_32Key);
            var IV = Hash.Take(16).ToArray();

            // Check arguments.
            if (Data == null || Data.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            byte[] encrypted;
            using (var rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Hash;
                rijAlg.IV = IV;
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                            swEncrypt.Write(Data);
                    encrypted = msEncrypt.ToArray();
                }
            }
            return Convert.ToBase64String(encrypted);
        }
        public static string AESDecrypt(string cipherText, string Key)
        {
            using (RijndaelManaged myRijndael = new RijndaelManaged())
            {
                // Check arguments.
                if (cipherText == null || cipherText.Length <= 0)
                    throw new ArgumentNullException("cipherText");
                if (Key == null || Key.Length <= 0)
                    throw new ArgumentNullException("Key");
                byte[] content = Convert.FromBase64String(cipherText);
                byte[] hash = Encoding.UTF8.GetBytes(Key.ToHashString());
                byte[] iv = hash.Take(16).ToArray();

                if (iv == null || iv.Length <= 0)
                    throw new ArgumentNullException("IV");
                string plaintext = null;
                using (RijndaelManaged rijAlg = new RijndaelManaged())
                {
                    rijAlg.Key = hash;
                    rijAlg.IV = iv;
                    ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
                    using (MemoryStream msDecrypt = new MemoryStream(content))
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        plaintext = srDecrypt.ReadToEnd();
                }
                return plaintext;
            }
        }
    }
}
